import datetime
from typing import List, Dict

from sqlalchemy import Column, DateTime, Date, DECIMAL, String, Index, BigInteger, and_, func
from sqlalchemy.orm import Session

from common.database import Base
from common.database import SessionMixin


class KuduTableInfo(Base, SessionMixin):
    __tablename__ = 'bigdata_kudu_table_info'
    table_id = Column(String(40), nullable=False, comment="表ID")
    database_name = Column(String(128), nullable=False, comment="库名称")
    table_name = Column(String(128), nullable=False, comment="表名称")
    row_count = Column(BigInteger, nullable=False, comment="总行数")
    raw_capacity = Column(BigInteger, nullable=False, comment="原始容量")
    capacity = Column(String(40), nullable=False, comment="容量")
    create_date = Column(Date, default=datetime.date.today, nullable=True, comment="创建日期")
    create_time = Column(DateTime, default=datetime.datetime.now, nullable=False, comment="创建时间")

    __table_args__ = (
        Index('idx_bigdata_kudu_table_info_uuid', 'uuid', unique=True),
        Index('idx_bigdata_kudu_table_info_database_name', 'database_name'),
        Index('idx_bigdata_kudu_table_info_table_name', 'table_name'),
        Index('idx_bigdata_kudu_table_info_create_date', 'create_date'),
        Index('idx_bigdata_kudu_table_info_create_time', 'create_time'),
        {
            'mysql_engine': 'innodb',
            'mysql_charset': 'utf8mb4',
            'mysql_collate': 'utf8mb4_unicode_ci',
            'extend_existing': True,
            'mysql_row_format': 'dynamic',
        }
    )

    def __repr__(self):
        return "<database_name='{} ,table_name='{} ,create_time='{}'>".format(self.database_name, self.table_name, self.create_time)

    @classmethod
    def get_latest_time(cls, db: Session) -> Dict:
        return db.query(cls).with_entities(cls.create_time).order_by(cls.create_time.asc()).limit(1).to_dict_first()

    @classmethod
    def get_data_by_latest_time(cls, page: int, per_page: int, create_time: str, db: Session) -> Dict:
        return db.query(cls).filter(cls.create_time == create_time).order_by(cls.create_time.asc()).paginate(
            page=page, per_page=per_page)

    @classmethod
    def get_data_by_create_date(cls, page: int, per_page: int, create_date: str, db: Session) -> List:
        return db.query(cls).filter(cls.create_date == create_date).paginate(page=page, per_page=per_page)

    @classmethod
    def get_db_data_by_date_range(cls, start_date: str, end_date: str, db: Session) -> List:
        return db.query(cls).with_entities(cls.database_name, func.sum(cls.raw_capacity).label('raw_capacity'),
                                           cls.create_date).filter(cls.create_date.between(start_date, end_date)).order_by(
            cls.create_date.desc()).group_by(cls.database_name, cls.create_date).to_dict()

    @classmethod
    def get_db_table_by_date_range(cls, start_date: str, end_date: str, db: Session) -> List:
        return db.query(cls).with_entities(func.concat_ws(".", cls.database_name, cls.table_name).label('table_name'), cls.capacity,
                                           cls.create_date.label('date')).filter(
            and_(cls.create_date.between(start_date, end_date), cls.row_count != 0)).to_dict()


if __name__ == '__main__':
    from common.database import SessionLocal

    session = SessionLocal()
    kudu_table_info = KuduTableInfo()
    print(kudu_table_info.get_db_table_by_date_range('2023-10-26', '2023-11-01', session))
